import React, { useRef, useState } from 'react';
import { useDrag, useDrop, DropTargetMonitor } from 'react-dnd';
import { XYCoord } from 'dnd-core';
import PropTypes from 'prop-types';
import { SettingOutlined, CloseOutlined } from '@ant-design/icons';
import { Popover } from 'antd';
import WdDlEditor from './WdDlEditor';
import styles from './index.module.scss';
import { WD_TYPE } from '../EnumConfig';

const ItemTypes = {
	BOX: 'card',
};

interface CardProps {
	// id: any;
	// text: string;
	// type: string;
	node: any;
	index: number;
	moveCard: ( dragIndex: number, hoverIndex: number ) => void;
	handleDelete: ( e:any, index: number ) => void;
	handleUpdate: ( value: any, index: number, unit?: boolean ) => void;
	chartType?: string;
	isShowSetting?: boolean;
	onItemClick?: any;
}

interface DragItem {
	index: number;
	id: string;
	type: string;
}

// eslint-disable-next-line react/prop-types
const SortItem: React.FC<CardProps> = ( { index, node, moveCard, handleDelete, handleUpdate, onItemClick, chartType, isShowSetting = true } ) => {
	const { id, title: text, modelType: type, childrenType, children } = node;
	const ref = useRef<HTMLDivElement>( null );
	const [ , drop ] = useDrop( {
		accept: ItemTypes.BOX,
		hover( item: DragItem, monitor: DropTargetMonitor ) {
			if ( !ref.current ) {
				return;
			}
			const dragIndex = item.index;
			const hoverIndex = index;

			// Don't replace items with themselves
			if ( dragIndex === hoverIndex ) {
				return;
			}

			// Determine rectangle on screen
			const hoverBoundingRect = ref.current?.getBoundingClientRect();

			// Get vertical middle
			const hoverMiddleY = ( hoverBoundingRect.bottom - hoverBoundingRect.top ) / 2;

			// Determine mouse position
			const clientOffset = monitor.getClientOffset();

			// Get pixels to the top
			const hoverClientY = ( clientOffset as XYCoord ).y - hoverBoundingRect.top;

			// Only perform the move when the mouse has crossed half of the items height
			// When dragging downwards, only move when the cursor is below 50%
			// When dragging upwards, only move when the cursor is above 50%

			// Dragging downwards
			if ( dragIndex < hoverIndex && hoverClientY < hoverMiddleY ) {
				return;
			}

			// Dragging upwards
			if ( dragIndex > hoverIndex && hoverClientY > hoverMiddleY ) {
				return;
			}

			// Time to actually perform the action
			moveCard( dragIndex, hoverIndex );

			// Note: we're mutating the monitor item here!
			// Generally it's better to avoid mutations,
			// but it's good here for the sake of performance
			// to avoid expensive index searches.
			item.index = hoverIndex;
		},
	} );

	const [ { isDragging }, drag ] = useDrag( {
		item: { type: ItemTypes.BOX, id, index },
		collect: ( monitor: any ) => ( {
			isDragging: monitor.isDragging(),
		} ),
	} );

	const opacity = isDragging ? 0 : 1;

	drag( drop( ref ) );

	const [ showDelete, setShowDelete ] = useState( false );

	const onMouseOver = () => {
		setShowDelete( true );
	};

	const onMouseLeave = () => {
		setShowDelete( false );
	};

	const deleteStyle = {
		color: 'red',
		display: 'inline-block',
		cursor: 'pointer',
		height: '27px',
		lineHeight: '27px',
	};
	const itemStyle = {
		border: '1px dashed gray',
		// padding: '0.2rem 0',
		// height: '27px',
		marginBottom: '.5rem',
		backgroundColor: type === WD_TYPE ? '#4c8dd8' : 'rgb(59, 185, 161)',
		color: '#fff',
		cursor: 'pointer',
		borderRadius: '2px',
		paddingLeft: showDelete ? '15px' : '5px',
		// 'box-sizing': 'border-box'
	};

	const ellipsisStyles = {
		overflow: 'hidden',
		display: 'inline-block',
		width: '90%',
		height: '27px',
		lineHeight: '27px',
		textOverflow: 'ellipsis',
		// 'white-space': 'nowrap',
		// whiteSpace: 'nowrap'
	};

	const childStyles = {
		overflow: 'hidden',
		display: 'inline-block',
		width: '90%',
		height: '20px',
		lineHeight: '20px',
		textOverflow: 'ellipsis',
		padding: 0,
		margin: 0,
	};

	return (
		<div
			ref={ref}
			style={{ ...itemStyle, position: 'relative', opacity }}
			onMouseOver={onMouseOver}
			onMouseLeave={onMouseLeave}
			onClick={( e ) => onItemClick && onItemClick( e, node )}
		>
			{/* !!showDelete && */}
			<div style={{ textAlign: 'left', lineHeight: 0, }}>
				{!!showDelete && (
					<span
						style={{ ...deleteStyle, position: 'absolute', top: '0px', left: '2px' }}
						onClick={( e ) => handleDelete( e, index )}
					>
						<CloseOutlined />
					</span>
				)}
				<span style={ellipsisStyles}>
					{node.originTitle ? (
						<>
							{node.originTitle}[{text}]
						</>
					) : (
						text
					)}
				</span>
			</div>
			{
				<div
					onClick={( e ) => {
						e.nativeEvent.stopImmediatePropagation();
					}}
				>
					<Popover
						placement="rightTop"
						style={{ padding: '0' }}
						className={styles.modify_container}
						content={
							<WdDlEditor
								handleDelete={handleDelete}
								node={node}
								handleUpdate={( node, unit ) => handleUpdate( node, index, unit )}
								chartType={chartType}
							></WdDlEditor>
						}
						trigger="click"
					>
						{
							isShowSetting && (
								<SettingOutlined
									style={{
										position: 'absolute',
										top: '7px',
										right: '4px',
										cursor: 'pointer',
									}}
								/>
							)
						}

					</Popover>
				</div>
			}

			{/* 自定义层级 */}
			{
				childrenType === 'FOLDER' && children && (
					<div style={ { paddingLeft: '16px' } }>
						{
							children.map( item => ( <p key={item.key} style={childStyles}>{ item.title }</p> ) )
						}
					</div>
				)
			}
		</div>
	);
};

SortItem.propTypes = {
	// id: PropTypes.string.isRequired,
	// text: PropTypes.string.isRequired,
	// type: PropTypes.string.isRequired,
	index: PropTypes.number.isRequired,
	moveCard: PropTypes.func.isRequired,
	handleDelete: PropTypes.func.isRequired,
	handleUpdate: PropTypes.func.isRequired,
	node: PropTypes.object.isRequired,
};

export default SortItem;
